home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hobby PC 15
/
Hobby PC 15.iso
/
Soft
/
Blender
/
blender.exe
/
ic255.cab
/
python
/
lwo2iv.py
< prev
next >
Wrap
Text File
|
2001-03-15
|
15KB
|
388 lines
#! /usr/bin/env python
#######################
# (c) Jan Walter 2000 #
#######################
# CVS
# $Author: jan $
# $Date: 2000/12/14 15:34:25 $
# $RCSfile: lwo2iv.py,v $
# $Revision: 1.1 $
# why not use the chunk module ???
import sys
import string
import struct
import os
def usage():
print 'usage: python lwo2iv.py "filename.lwo"'
def readChunk(file):
tag = file.read(4)
data = struct.unpack(">L", file.read(4)) # big endian
length = data[0]
return tag, length
def readFace(file):
bytes = 0
numvert = struct.unpack(">H", file.read(2)) # numvert
bytes = bytes + 2
numvert = numvert[0]
verts = []
for index in xrange(numvert):
vert = struct.unpack(">H", file.read(2)) # vert
bytes = bytes + 2
verts.append(vert[0])
surf = struct.unpack(">h", file.read(2)) # surf
bytes = bytes + 2
surf = surf[0]
face = numvert, verts, surf
return face, bytes
def readFaceList(file, length):
faceList = []
numFaces = 0
bytes = 0
while bytes < length:
face, numBytes = readFace(file)
bytes = bytes + numBytes
faceList.append(face)
print "numFaces:", len(faceList)
return faceList
def readPoint(file):
return struct.unpack(">3f", file.read(12)) # big endian
def readPointList(file, length):
pointList = []
numPoints = length / 12
print "numPoints:", numPoints
for index in xrange(numPoints):
point = readPoint(file)
pointList.append(point)
return pointList
def readSurfaceDefinition(file, length):
surfaceDefinition = []
bytes = file.read(length)
words = string.split(bytes, '\0')
bytes = bytes[(len(words[0])+1):]
# skip \0
while bytes[0] == '\0':
bytes = bytes[1:]
while bytes != '':
subChunk, bytes = readSurfaceSubChunk(bytes)
surfaceDefinition.append(subChunk)
return surfaceDefinition
def readSurfaceSubChunk(bytes):
subChunk = []
tag = bytes[:4]
bytes = bytes[4:]
data = struct.unpack(">H", bytes[:2])
bytes = bytes[2:]
length = data[0]
if tag in ["COLR", "TCLR"]:
subChunk.append(tag)
r, g, b, pad = struct.unpack(">4B", bytes[:4])
bytes = bytes[4:]
subChunk.append((r, g, b))
elif tag in ["FLAG", "RFLT", "TFLG", "TFRQ"]:
subChunk.append(tag)
value = struct.unpack(">H", bytes[:2])
value = value[0]
bytes = bytes[2:]
subChunk.append(value)
elif (tag in ["LUMI", "DIFF", "SPEC", "REFL", "TRAN", "GLOS", "TVAL"] or
tag[:3] == "TIP"):
subChunk.append(tag)
value = struct.unpack(">h", bytes[:2])
value = value[0]
bytes = bytes[2:]
subChunk.append(value)
elif (tag in ["VLUM", "VDIF", "VSPC", "VRFL", "VTRN", "RSAN", "RIND",
"EDGE", "SMAN", "TAMP", "TAAS", "TOPC"] or
tag[:3] == "TFP" or tag[:3] == "TSP"):
subChunk.append(tag)
value = struct.unpack(">f", bytes[:4])
value = value[0]
bytes = bytes[4:]
subChunk.append(value)
elif tag in ["RIMG", "CTEX", "DTEX", "STEX", "RTEX", "TTEX", "LTEX",
"BTEX", "TIMG", "TALP"]:
subChunk.append(tag)
words = string.split(bytes, '\0')
filename = words[0]
bytes = bytes[(len(words[0])+1):]
# skip \0
while bytes[0] == '\0':
bytes = bytes[1:]
subChunk.append(filename)
elif tag in ["TSIZ", "TCTR", "TFAL", "TVEL"]:
subChunk.append(tag)
values = struct.unpack(">3f", bytes[:12]) # big endian
bytes = bytes[12:]
subChunk.append(values)
elif tag == "TWRP":
subChunk.append(tag)
values = struct.unpack(">HH", bytes[:4])
bytes = bytes[4:]
subChunk.append(values)
else:
print tag
bytes = bytes[length:]
return subChunk, bytes
def readSurfaceList(file, length):
bytes = file.read(length)
words = string.split(bytes, '\0')
surfaceList = []
for word in words:
if word:
surfaceList.append(word)
return surfaceList
def isOnePolygon(indices):
for i in xrange(len(indices) - 1):
if indices[i] in (indices[0:i] + indices[(i+1):]):
return 0
return 1
def haveCommonCoords(pointList, indices, index):
testValue = pointList[0][index]
for i in indices:
if (pointList[i][index] - testValue) > 0.001:
return 0
return 1
def convertToInnerLoops(indices):
equal = []
outer = []
inner = []
# remove inner loops
for i in xrange(len(indices)):
for j in xrange(i+1, len(indices)):
if i != j and indices[i] == indices[j]:
equal.append([i, j])
if (len(equal) == 2 and equal[0][0] == (equal[1][0] - 1) and
equal[0][1] == (equal[1][1] + 1)):
outer = indices[:equal[0][0]] + indices[equal[0][1]:]
inner = indices[equal[1][0]:equal[1][1]]
## print equal
## print indices
## print outer
## print inner
return outer, inner
def testLwo2iv(filename):
print 'testLightwave("%s")' % filename
file = open(filename, "rb")
tag, length = readChunk(file)
if tag == "FORM":
lwob = file.read(4)
if lwob == "LWOB":
filelength = length
numBytes = 4
while (numBytes < filelength):
tag, length = readChunk(file)
numBytes = numBytes + 8
if length % 2 != 0:
print "usage of pad byte"
length = length + 1
# surface list
if tag == "SRFS":
surfaceList = readSurfaceList(file, length)
# point list
elif tag == "PNTS":
pointList = readPointList(file, length)
# face list
elif tag == "POLS":
faceList = readFaceList(file, length)
# surface definition
elif tag == "SURF":
surfaceDefinition = readSurfaceDefinition(file, length)
else:
file.read(length)
numBytes = numBytes + length
else:
print 'No "LightWave 3D Object File Format" found :-['
file.close()
#########################
# write to OpenInventor #
#########################
file = open("test.iv", "w")
print "exporting ..."
# header
file.write("#Inventor V2.1 ascii\n\n")
file.write("Separator {\n")
file.write(" ShapeHints {\n")
file.write(" vertexOrdering COUNTERCLOCKWISE\n")
file.write(" }\n")
# vertices
file.write(" Coordinate3 {\n")
file.write(" point [\n")
for vertex in pointList[:-1]:
file.write(" %s %s %s,\n" %
(vertex[0], vertex[1], vertex[2]))
vertex = pointList[-1]
file.write(" %s %s %s\n" %
(vertex[0], vertex[1], vertex[2]))
file.write(" ]\n")
file.write(" }\n")
# faces
for materialIndex in xrange(1, len(surfaceList) + 1):
file.write(" Separator {\n")
file.write(" # %s\n" % surfaceList[materialIndex-1])
file.write(" Material {\n")
file.write(" diffuseColor 1 1 1\n")
file.write(" }\n")
file.write(" IndexedFaceSet {\n")
file.write(" coordIndex [\n")
for face in faceList:
numvert, vert, surf = face
if surf == materialIndex:
if numvert == 3:
file.write(" %s, %s, %s, -1,\n" %
(vert[0], vert[1], vert[2]))
elif numvert == 4:
file.write(" %s, %s, %s, %s, -1,\n" %
(vert[0], vert[1], vert[2], vert[3]))
## else:
## print face
file.write(" ]\n")
file.write(" }\n")
# all non-triangles and non-quads
# -------------------------------
# try to export some of them
file.write(" # %s\n" % surfaceList[materialIndex-1])
file.write(" Material {\n")
file.write(" diffuseColor 0 1 0\n")
file.write(" }\n")
file.write(" IndexedFaceSet {\n")
file.write(" coordIndex [\n")
for face in faceList:
numvert, vert, surf = face
if surf == materialIndex:
# one polygon
if numvert != 3 and numvert != 4 and isOnePolygon(vert):
testIndex = -1
if haveCommonCoords(pointList, vert, 0):
testIndex = 0
tmpFile = open("data", "w")
tmpFile.write("1\n\n%s\n" % len(vert))
for i in vert:
tmpFile.write("%s %s\n" % (pointList[i][1],
pointList[i][2]))
tmpFile.close()
if haveCommonCoords(pointList, vert, 1):
testIndex = 1
tmpFile = open("data", "w")
tmpFile.write("1\n\n%s\n" % len(vert))
for i in vert:
tmpFile.write("%s %s\n" % (pointList[i][0],
pointList[i][2]))
tmpFile.close()
if haveCommonCoords(pointList, vert, 2):
testIndex = 2
tmpFile = open("data", "w")
tmpFile.write("1\n\n%s\n" % len(vert))
for i in vert:
tmpFile.write("%s %s\n" % (pointList[i][0],
pointList[i][1]))
tmpFile.close()
if testIndex != -1:
tmpFile = os.popen("./triangulate data\n")
info = tmpFile.readlines()
tmpFile.close()
for line in info:
words = string.split(line)
v1 = int(words[2]) - 1
v2 = int(words[3]) - 1
v3 = int(words[4]) - 1
file.write(" %s, %s, %s, -1,\n" %
(vert[v1], vert[v2], vert[v3]))
# polygon with subloops
## if numvert != 3 and numvert != 4 and not isOnePolygon(vert):
## outer, inner = convertToInnerLoops(vert)
## testIndex = -1
## if haveCommonCoords(pointList, outer, 0):
## testIndex = 0
## tmpFile = open("data", "w")
## tmpFile.write("2\n\n%s\n" % len(outer))
## for i in outer:
## tmpFile.write("%s %s\n" % (pointList[i][1],
## pointList[i][2]))
## tmpFile.write("\n%s\n" % len(inner))
## for i in inner:
## tmpFile.write("%s %s\n" % (pointList[i][1],
## pointList[i][2]))
## tmpFile.close()
## if haveCommonCoords(pointList, outer, 1):
## testIndex = 1
## tmpFile = open("data", "w")
## tmpFile.write("2\n\n%s\n" % len(outer))
## for i in outer:
## tmpFile.write("%s %s\n" % (pointList[i][0],
## pointList[i][2]))
## tmpFile.write("\n%s\n" % len(inner))
## for i in inner:
## tmpFile.write("%s %s\n" % (pointList[i][0],
## pointList[i][2]))
## tmpFile.close()
## if haveCommonCoords(pointList, outer, 2):
## testIndex = 2
## tmpFile = open("data", "w")
## tmpFile.write("2\n\n%s\n" % len(outer))
## for i in outer:
## tmpFile.write("%s %s\n" % (pointList[i][0],
## pointList[i][1]))
## tmpFile.write("\n%s\n" % len(inner))
## for i in inner:
## tmpFile.write("%s %s\n" % (pointList[i][0],
## pointList[i][1]))
## tmpFile.close()
## if testIndex != -1:
## tmpFile = os.popen("./triangulate data\n")
## info = tmpFile.readlines()
## tmpFile.close()
## for line in info:
## words = string.split(line)
## v1 = int(words[2]) - 1
## v2 = int(words[3]) - 1
## v3 = int(words[4]) - 1
## file.write(" %s, %s, %s, -1,\n" %
## (vert[v1], vert[v2], vert[v3]))
file.write(" ]\n")
file.write(" }\n")
# the rest of non-triangles and non-quads
file.write(" Material {\n")
file.write(" diffuseColor 1 0 0\n")
file.write(" }\n")
file.write(" IndexedLineSet {\n")
file.write(" coordIndex [\n")
for face in faceList:
numvert, vert, surf = face
if surf == materialIndex:
if numvert != 3 and numvert != 4:
file.write(" ")
for i in xrange(numvert):
file.write("%s, " % vert[i])
file.write("-1,\n")
file.write(" ]\n")
file.write(" }\n")
file.write(" }\n")
# finish
file.write("}\n")
print "... finished"
file.close()
if __name__ == "__main__":
if len(sys.argv) != 2:
usage()
else:
filename = sys.argv[1]
testLwo2iv(filename)